/*
 * AppointmentPanel.java
 */
package edu.gatech.oad.schedule;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.mail.MessagingException;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.TitledBorder;

import edu.gatech.oad.ui.UserPanel;
import edu.gatech.oad.user.AccountsController;
import edu.gatech.oad.user.Doctor;
import edu.gatech.oad.user.MedicalPersonnelAvailability;
import edu.gatech.oad.user.Patient;


public class AppointmentPanel extends JPanel{
	private static final long serialVersionUID = 1L;

	private final GridBagConstraints gbc = new GridBagConstraints();
	
	private  List<JCheckBox> symptoms = new ArrayList<JCheckBox>();
	
	private final String[] sympTitles = {"Abominal Pain", "Allergies", "Back Pain",
			"Blood in Stool", "Blood in Urine", "Breast Lump/Pain", "Breathing Troubles", 
			"Chest Pain", "Cold/Flu/Ear Pain", "Constipation", "Cough", "Diarrhea",
			"Eye Problems", "Fatigue/Tired", "Fever", "Headace/Migraine", 
			"High blood pressure", "Insomnia", "Joint Pain/Injury", "Mole/Lump", 
			"Other/Personal", "Pain with Urination", "Penile Discharge", 
			"Sore Throat", "STD - Female", "STD - Male", "Skin Problems",
			"Testicular Pain/Lump", "Wart"};
	
	private final List<String> symptomsSelected = new ArrayList<String>();
	
	private List<MedicalPersonnelAvailability> listOfFreeSched = new ArrayList<MedicalPersonnelAvailability>();

	
	private final JPanel availableAppointments = new JPanel(), 
		datePanel = new JPanel(), symptomPanel = new JPanel();
	
	private final JButton submitAppt = new JButton("Submit Appointment");
	
	private JList list;
	
	private Patient patient;
	
	private Doctor doctorForAppointment;
	
	private JComboBox days, months, years, doctors;
	
	private int dayNumber, monthNumber, yearNumber;
	
	private UserPanel userPanel;
	
	private JScrollPane listOfAppointments;
	/**
	 * 
	 * @param patient
	 */
	public AppointmentPanel(Patient patient, UserPanel userPanel){
		this.patient = patient;
		this.userPanel = userPanel;
		addToPatientAppointmentPanel(patient);
	}
	
	private void addToPatientAppointmentPanel(Patient patient){
		this.setBackground(Color.white);
		setLayout(new GridBagLayout());
		gbc.anchor = GridBagConstraints.PAGE_START;
		addSymptoms();
		gbc.anchor = GridBagConstraints.FIRST_LINE_START;
		gbc.gridheight = 1;
		gbc.gridx = 1;
		addDateSearchDropBoxes();
		gbc.weighty = 2;
		addAvailableAppointments();
	}
	
	private void addAvailableAppointments() {
		availableAppointments.setBorder(new TitledBorder("Available Appointments"));
		availableAppointments.setPreferredSize(new Dimension(500, 325));
		availableAppointments.setLayout(new BoxLayout(availableAppointments, 
				BoxLayout.Y_AXIS));
		availableAppointments.setBackground(Color.white);
		submitAppt.addActionListener(new SubmitAppointmentListener());
		gbc.gridy = 1;
		gbc.weightx = 1;
		add(availableAppointments, gbc);
	}
	
	private void addDateSearchDropBoxes(){
		datePanel.setBorder(new TitledBorder("Appointment Date"));
		datePanel.setPreferredSize(new Dimension(500, 75));
		datePanel.setBackground(Color.white);
		final Calendar cal = Calendar.getInstance();
		
		final Integer[] monthArray = new Integer[32];
		for(int i = 1; i < 13; i++){
			monthArray[i] = i;
		}
		months = new JComboBox(monthArray);
		months.setSelectedItem(cal.get(Calendar.MONTH) + 1);
		datePanel.add(months);
		
		final Integer[] dayArray = new Integer[32];
		for(int i = 1; i < 32; i++){
			dayArray[i] = i;
		}
		days = new JComboBox(dayArray);
		days.setSelectedItem(cal.get(Calendar.DATE));
		datePanel.add(days);
		
		final Integer[] yearArray = new Integer[100];
		for(int i = 1; i < 100; i++){
			yearArray[i] = 2010 + i;
		}
		
		years = new JComboBox(yearArray);
		years.setSelectedItem(cal.get(Calendar.YEAR));
		datePanel.add(years);
		
		int numOfDocs = AccountsController.sharedController().getDoctors().size();
		String[] listOfDoctors = new String[numOfDocs + 1];
		int docCount = 1;
		for(Doctor docs : AccountsController.sharedController().getDoctors()){
			listOfDoctors[docCount] = docs.getName();
			docCount++;
		}
		doctors = new JComboBox(listOfDoctors);
		datePanel.add(doctors);
		
		JButton search = new JButton("Search Appointments");
		search.addActionListener(new SearchListener());
		datePanel.add(search);
		add(datePanel, gbc);
	}
	
	private void addSymptoms(){
		symptomPanel.setBorder(new TitledBorder("Please Choose Your Symptoms"));
		symptomPanel.setLayout(new GridLayout(15, 2));
		symptomPanel.setPreferredSize(new Dimension(250, 400));
		symptomPanel.setBackground(Color.white);
		symptoms = new ArrayList<JCheckBox>();

		int count = 0;
		for(String i : sympTitles){
			symptoms.add(new JCheckBox(i));
			symptoms.get(count).addItemListener(new SymptomListener());
			symptomPanel.add(symptoms.get(count));
			count++;
		}
		gbc.gridheight = 2;
		add(symptomPanel, gbc);
	}
	
	private class SymptomListener implements ItemListener{
		public void itemStateChanged(ItemEvent e) {
			int count = 0;
			symptomsSelected.clear();
			for(String i : sympTitles){
				if(symptoms.get(count).isSelected()){
					symptomsSelected.add(i);
				}
				count++;
			}
		}
	}
	
	private class SearchListener implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			//Once Doctor Schedules are updated
			//the following codes will be changed
			dayNumber = days.getSelectedIndex();
			monthNumber = months.getSelectedIndex();
			yearNumber = years.getSelectedIndex() + Calendar.getInstance().get(Calendar.YEAR) - 1;
			
			for(Doctor docs : AccountsController.sharedController().getDoctors()){
				if(docs.getName().equals(doctors.getSelectedItem())){
					doctorForAppointment = docs;
				}
			}
			
			List<String> openSpots = new ArrayList<String>(); 
			if((dayNumber == -1 && monthNumber == -1 && yearNumber == -1) && doctors.getSelectedIndex() != -1){
				for(MedicalPersonnelAvailability mpa : CalendarController.sharedCalendarController().search(doctorForAppointment)){
					openSpots.add(mpa.toString() + " - " + doctorForAppointment.getLastName());
					listOfFreeSched.add(mpa);
				}
			}
			else if((days.getSelectedIndex() != -1 && months.getSelectedIndex() != -1 && years.getSelectedIndex() != -1) && doctors.getSelectedIndex() == -1){
				int count = 0;
				for(MedicalPersonnelAvailability mpa : CalendarController.sharedCalendarController().search(dayNumber, monthNumber, yearNumber)){
					openSpots.add(mpa.toString() + " - " + mpa.getDoctor().getLastName());
					listOfFreeSched.add(mpa);
				}
			} 
			else if((days.getSelectedIndex() != -1 && months.getSelectedIndex() != -1 && years.getSelectedIndex() != -1)){
				for(MedicalPersonnelAvailability mpa : CalendarController.sharedCalendarController().search(dayNumber, monthNumber, yearNumber)){
					openSpots.add(mpa.toString() + " - " + mpa.getDoctor().getLastName());
					listOfFreeSched.add(mpa);
				}
			}
			else{
				JOptionPane.showMessageDialog(null, "Cannot find appointments with given inputs, please try again", 
						"Appointment Warning", JOptionPane.WARNING_MESSAGE);
			}
			if(listOfAppointments != null){availableAppointments.remove(listOfAppointments);}
			list = new JList(openSpots.toArray());
			list.setSelectedIndex(0);
			if(openSpots.size() == 0) submitAppt.setEnabled(false);
			else submitAppt.setEnabled(true);

			listOfAppointments = new JScrollPane(list);
			availableAppointments.add(listOfAppointments);
			availableAppointments.add(submitAppt);
			submitAppt.setAlignmentX(Component.CENTER_ALIGNMENT);
			availableAppointments.updateUI();
			
		}
	}
	
	private class SubmitAppointmentListener implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			MedicalPersonnelAvailability selectedMPA = listOfFreeSched.get(list.getSelectedIndex()); 
			int confirm = JOptionPane.showConfirmDialog(null, "Are you sure that you would like the appointment on \n" +
					selectedMPA.toString(), "Confirm Appointment", JOptionPane.YES_NO_OPTION, 
					JOptionPane.PLAIN_MESSAGE);
				
			if (confirm == JOptionPane.YES_OPTION){
				Calendar cal = GregorianCalendar.getInstance();
				cal.set(selectedMPA.getYear(),
						selectedMPA.getMonth(),
						selectedMPA.getDay(),
						selectedMPA.getHour(),
						selectedMPA.getYear());
				Date date = cal.getTime();
			
				Appointment appt = new Appointment(date, symptomsSelected);
				AppointmentController apptController = 
					new AppointmentController(patient, 	listOfFreeSched.get(list.getSelectedIndex()).getDoctor());
	
				apptController.save(appt);
				String emailAddress = patient.getEmailAddress();
				String emailSubject = "New Appointment";
				String greeting = "Hello";
				Calendar currentTime =  new GregorianCalendar();
				int currentHour = currentTime.get(Calendar.HOUR_OF_DAY);
				if (currentHour < 12 && currentHour >= 0) greeting = "Good Morning";
				if (currentHour < 24 && currentHour >= 18) greeting = "Good Evening";
				if (currentHour < 18 && currentHour >= 12) greeting = "Good Afternoon";
				
				String emailBody = greeting + " " + patient.getFirstName() +  " " + patient.getLastName() + ", \n" +
						"You have recently submitted an appointment for the following date and time: " + 
						listOfFreeSched.get(list.getSelectedIndex()).toString()	+ " for the following reasons: " 
						+ appt.getReason() + ". Please arrive 15 minutes before your scheduled appointment time. \n  \n" +
						"If you are unable to make your appoinment please call 2 hours in advance (Number) and cancel to " +
						"avoid the no show fee. \n \n This is an automated message, please do not reply.";
				try {
					Email apptEmail = new Email(emailAddress, emailSubject, emailBody);
					apptEmail.sendEmail();
				} catch (MessagingException e1) {
					e1.printStackTrace();
				}
				
				submitAppt.setText("Submitted");
				submitAppt.setEnabled(false);
				userPanel.getTabbedPane().remove(userPanel.getTabbedPane().getSelectedIndex());
				userPanel.addNewTab(patient.getFirstName() + "'s Appointments",new AppointmentViewPanel(patient, userPanel));
				
			}
		}
	}

}

